package net
{
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.net.Socket;
	import flash.utils.ByteArray;
	import flash.utils.Endian;
	import flash.utils.setTimeout;
	
	import model.user.User;
	
	import ricky.plutonium.Application;
	
	
	/**
	 * socket链接
	 */
	public class SocketProxy 
	{
		private static var _soc:Socket;
		
		public static function get socket():Socket
		{
			if(!_soc)
			{
				_soc=new Socket();
				_soc.endian=Endian.BIG_ENDIAN;
				_soc.addEventListener(Event.CLOSE,onClose);
				_soc.addEventListener(Event.CONNECT,onConnect);
				_soc.addEventListener(IOErrorEvent.IO_ERROR,ioError);
				_soc.addEventListener(ProgressEvent.SOCKET_DATA,onReceive);
				_soc.addEventListener(SecurityErrorEvent.SECURITY_ERROR,onSecurtyError);
				buffer=new ByteArray();
//				var a:Array
//				registerClassAlias("flex.messaging.io.ArrayCollection", mx.collections.ArrayCollection);
			}
			return _soc;
		}
		
		private static var Host:String;
		private static var Port:int;
		
		public static function get connected():Boolean
		{
			return socket.connected;
		}
		
		/**
		 * connect to server 
		 */
		public static function connect(host:String,port:int):void
		{
			Host=host;
			Port=port;
			socket.connect(host,port);
		}
		 
	
		/**
		 * 发送消息到服务端
		 */
		private static function sendBytes(bytes:ByteArray):void
		{
			if(_soc.connected)
			{
				bytes.position=0;
				if(bytes.length>4)
				{
					_soc.writeInt(bytes.length);
					_soc.writeBytes(bytes);
					_soc.flush();
				}
				bytes.clear();			
			}
		}
		
		public static function send(obj:Object):void
		{
			var bytes:ByteArray=new ByteArray();
			bytes.endian=Endian.BIG_ENDIAN;
			bytes.writeObject(obj);
			sendBytes(bytes);
		}
		//protected
		
		private static var buffer:ByteArray;
		/**
		 * 收到服务端消息
		 */
		protected static function onReceive(e:ProgressEvent):void
		{
			var len:int = 0;
			var cmd:int = 0;
			
			while(socket.connected)
			{
				if (buffer.length == 0)
				{
					if (_soc.bytesAvailable < 4)
						break;
					_soc.readBytes(buffer,0,4);
				}
				buffer.position = 0;
				len = buffer.readInt();
				if (_soc.bytesAvailable < len)
					break;
				buffer.length = 0;
				if (len >0)
					_soc.readBytes(buffer,0,len);
				
				var buff:ByteArray=new ByteArray();
				buff.endian=Endian.BIG_ENDIAN;
				buff.writeBytes(buffer,0,buffer.length);
				deCode(buff);
				buffer.length = 0;
			}

		}
		
		/**
		 * 链接关闭
		 */
		protected static function onClose(e:Event):void
		{
			trace("当前链接已经关闭");
		}
		
		/**
		 * 链接成功的时候调用
		 */
		protected static function onConnect(e:Event):void
		{
			trace("已经链接成功！");
			var d:Date=new Date();
			var obj:Object=new Object();
			obj["cmd"]="Connect";
			obj["name"]=User.userName;//"falsh"+d.hours+"_"+d.minutes;
			
			setTimeout(function():void{send(obj);},300);
			
//			var b:ByteArray=new ByteArray();
//			b.writeUTF("<policy-file-request/>");
//			sendBytes(b);
		}
		
		/**
		 * io读取出错
		 */
		protected static function ioError(e:IOErrorEvent):void
		{
			trace("io出错"+e.text+e);
		}
		
		/**
		 * 安全错误
		 */
		protected static function onSecurtyError(e:SecurityErrorEvent):void
		{
			trace("安全错误"+e.text);
		}
		
		/**
		 * 解包程序
		 * 协议 长度 方法名 参数
		 */
		protected static function deCode(bytes:ByteArray):void
		{
			bytes.position=0;
			var obj:Object=bytes.readObject();
			WorkQueue.instance.pushRecive(obj);
//			JDebug.trace("收到服务端消息"+obj.cmd+obj.arg);
		}

	}
}